package com.dx.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;

import com.dx.constants.Constants;
import com.dx.constants.StatsConstant;
import com.dx.entity.bo.Employee;
import com.dx.entity.dto.EmployeeDto;
import com.dx.entity.dto.EmployeeQueryDto;
import com.dx.entity.dto.LoginDto;
import com.dx.entity.vo.EmployeeVo;
import com.dx.exception.*;
import com.dx.mapper.EmployeeMapper;
import com.dx.properties.JwtProperties;
import com.dx.result.PageResult;
import com.dx.service.EmployeeService;
import com.dx.utils.JwtUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;


@RequiredArgsConstructor
@Service
@Slf4j
public class EmployeeServiceImpl implements EmployeeService {
    private final EmployeeMapper employeeMapper;
    private final JwtProperties jwtProperties;
    private final RedisTemplate redisTemplate;


    @Override
    public boolean updateStatus(Long id, int status) {
        if(status!= StatsConstant.ENABLE && status!=StatsConstant.DISABLE){
            throw new ArgumentException("输入了未知状态");
        }
//        log.info("更新员工状态，员工id：{}，状态：{}",id,status);
//        final Employee employee = Employee.builder().id(id).status(status).build();
//        log.info("更新员工状态，员工：{}",employee);
//        return employeeMapper.update(employee);
        return employeeMapper.updateStatus(id,status);
    }

    @Override
    public Employee getByEmail(String email) {
        return employeeMapper.getByEmail(email);
    }

    /**
     * 运行时异常不需要在方法或构造函数的 throws 子句中声明。
     */
    @Override
    //TODO 构建EmployeeInfo实体类
    public String login(LoginDto loginDto)  {
        if (loginDto==null) {
            throw  new ArgumentException("登录请求体为空");
        }

        String userName = loginDto.getUsername();
        if (userName==null) {
            throw new ArgumentException("username不能为空");
        }
        String passWord = loginDto.getPassword();
        if (passWord==null) {
            throw new ArgumentException("password不能为空");
        }
        Employee employee=null;
        log.info("用户名：{}",userName);
        employee = employeeMapper.getByUserName(userName);


        if (employee==null) {
            throw new UserNotExistException("该用户不存在");
        }
        log.info(employee.getPassword());
        if(employee.getStatus()==StatsConstant.DISABLE){
            throw new UserNotAcctivationException("用户未激活");
        }
        passWord=DigestUtils.md5DigestAsHex(passWord.getBytes());
        log.info(passWord);
        if (!employee.getPassword().equalsIgnoreCase(passWord)) {
            throw new PasswordException("密码错误");
        }
        String uuid = UUID.randomUUID().toString();
        //TODO 把uuid和查到的个人信息放到redis中
        redisTemplate.opsForValue().set(uuid,employee);
        final Employee employee1 = (Employee) redisTemplate.opsForValue().get(uuid);
        System.out.println("employee1 = " + employee1);
        HashMap<String, Object> claims = new HashMap<>();
        claims.put(Constants.uuId,uuid);
        String jwtToken=JwtUtil.createToken(claims,jwtProperties.getSecretKey(),jwtProperties.getTtl());



        final Claims data = JwtUtil.parseToken(jwtToken, jwtProperties.getSecretKey());
        if(data==null){
            throw new JwtTokenException("未解析到用户信息");
        }
        else if (data.getExpiration().before(new Date())) {
            throw new JwtTokenException("jwt token过期");
        }
        //TODO 常量类
        String id = data.get(Constants.uuId,String.class);
        System.out.println("id = " + id);
//        JwtUtil.verfyToken(jwtToken);


        System.out.println("jwtProperties.getExTime() = " + jwtProperties.getTtl());
        System.out.println("jwtProperties.getPassWord() = " + jwtProperties.getSecretKey());
        System.out.println("jwtProperties = " + Constants.tokenName);


        return jwtToken;

//        claims.put(Constans.username,employee.getUsername());
//        EmployeeInfo employeeInfo=BeanUtil.copyProperties(employee1,EmployeeInfo.class);
//        return employeeInfo;


    }


    //TODO 实现方法快捷键
    @Override
    public EmployeeDto save(EmployeeDto employeeDto) {

        //对象属性拷贝
        //Employee employee=new Employee();
        //BeanUtils.copyProperties(employeeDto,employee);

        //假如用户自主注册，那么就不应该存在createUser
        //如果需要登录才能注册，
        //employee.setCreateUser(ContextHolder.getUser().getId());

        Employee employee = BeanUtil.copyProperties(employeeDto, Employee.class);
        employee.setCreateTime(LocalDateTimeUtil.now());
        employee.setUpdateTime(LocalDateTimeUtil.now());
//        employee.setCreateUser(ContextHolder.getUser().getId());
//        employee.setUpdateUser(ContextHolder.getUser().getId());
        //表示用户自主注册
        employee.setPassword(DigestUtils.md5DigestAsHex(employeeDto.getPassword().getBytes()));
        employee.setCreateUser(-1L);
        employee.setUpdateUser(-1L);
        //表示用户账号还没有激活
        employee.setStatus(StatsConstant.DISABLE);
        employeeMapper.save(employee);
        return BeanUtil.copyProperties(employee,EmployeeDto.class);
    }

    @Override
    public PageResult<?> pageQuery(EmployeeQueryDto employeeQueryDto) {
        // 确保分页插件已正确配置并启动分页
        PageHelper.startPage(employeeQueryDto.getPageNum(), employeeQueryDto.getPageSize());

        // 查询分页数据
        Page<Employee> page = employeeMapper.pageQuery(employeeQueryDto);

        // 检查分页对象是否为空
        if (page == null) {
            log.warn("分页查询结果为空");
            return PageResult.page(0L, List.of());
        }

        // 获取结果集
        List<Employee> result = page.getResult();
        
        // 使用占位符方式记录日志，避免潜在的格式化问题
        log.info("Total: {}, Result Size: {}", page.getTotal(), result.size());

        // 将 Employee 转换为 EmployeeDto
        return PageResult.page(page.getTotal(), BeanUtil.copyToList(result, EmployeeVo.class));
    }
}
